chdkfandomcom-20200222-history
Lua/Lua Reference
=Lua Scripting functions= This is the reference page for Lua functions which do not have an equivalent command in ubasic, or are significantly modified compared to the ubasic equivalent. Most of the uBASIC commands are also available in Lua and can be used the same way, so UBASIC/TutorialScratchpad and Script_commands can be used as reference also for Lua. See also the Scripting Cross Reference Page for the complete list of CHDK scripting commands for Lua and uBASIC. Lua Standard Libraries Functions in this section are only available in Lua I/O functions In Lua there are also I/O library functions for file manipulation available, see *Lua Standard libraries OS system functions In Lua there are also OS library functions for operating system calls available, see *Lua Standard libraries String manipulation functions The standard Lua string library is available. *Lua Standard libraries Lua Functions Functions in this section are only available in Lua peek (since changeset #468) value = peek(address,size) Return the value in memory at the given address, or nil if the address alignment or size is invalid. size is one of 1, 2 or 4, and specifies to whether to read a byte, half word, or word. Default is 4. (since changeset #864) poke (since changeset #520) status = poke(address,value,size) Set the memory at address to value. Returns true, or nil if the address allignment or size is invalid. size is one of 1, 2 or 4, and specifies to whether to write a byte, half word, or word. Default is 4. (since changeset #864) bitwise operations (since changeset #468) bitand bitor bitxor bitshl bitshri bishru bitnot →''' perform the like named bitwise operations. These work as functions, not as operators, e.g.: c = bitand(a, b) bitshri '''→ performs an arithmetic (sign extending) right shift. bitshru →''' performs a logical (non-sign extending) right shift. get_buildinfo Returns information about the running platform and chdk version. Returns a table with the members : *platform *platformid *platsub *version *os *build_number *build_revision *build_date *build_time These fields can be used to make scripts work around camera differences without requiring users to set anything. bi=get_buildinfo() print("camera:"..bi.platform,"f/w:"..bi.platsub,"platformid:"..bi.platformid) print("version:"..bi.version.."-"..bi.build_number,"svn rev: "..bi.build_revision) print("built on:"..bi.build_date.." "..bi.build_time,"os:"..bi.os) '''Note: version currently returns just the string "CHDK". And build_number contains the entire build number as a string. get_prop (available since build 0.6.5 / changeset #541) With this command a Lua script can use PropertyCases without knowing the cameras propset and the propcase number. :get_prop (and set_prop) can be used with propcase.lua library which is included in the 'complete' download packages. This module loads a table which maps camera property case names the correct number for a given camera. :There are several different "property sets" known for CHDK cameras: Propset 1 on most Digic II cameras, propset 2 on most Digic III and some Digic IV, and further propsets on later Digic IV and Digic V. During the CHDK build process a Lua library with a table of the property case names and numbers is generated for each propset. These generated tables are saved in the \CHDK\LUALIB\GEN\ folder. The propcase.lua library automatically loads the correct propset table, allowing you to write scripts which use property cases by name, in a platform independent manner. Usage: props=require("propcase") tv=get_prop(props.TV) get_prop_str / set_prop_str / binstr (available since changeset #1306) The Lua commands get_prop_str, set_prop_str and binstr can be used to access arbitrary sized propcases from Lua. Usage: val=get_prop_str(prop_id,length) * get the value of a PropertyCase as a string * numeric values may be extracted using string.byte or or the binstr.lua module * returns the value as a string, or false if the underlying propcase call returned non-zero status=set_prop_str(prop_id,value) * set propertycase value as a string. Length is taken from the string * numeric propcase values may be assembled by setting byte values using string.char or the binstr module * status: boolean - true if the underlying propcase call returns 0, otherwise false → '''Both of the above use Lua strings, which can contain any sequence of bytes. '''binstr: Because many of the values you'd want to get/set at are numbers or arrays of numbers, a lua helper module called binstr is available to convert to and from strings for use with the above. The binstr module has 3 functions: string=binstr.pack(value,size) *value is a number or array of numbers *size is the number bytes to use from each number, default is 4, valid values are 1-4 *returns a lua string num=binstr.getnum(str[,size,pos]) *extract size bytes from string into number, starting at pos *size defaults to 4, *pos defaults to 1 *returns a number (without sign extension) or nil if pos is outside the string array=binstr.unpack(str,size) *split every size bytes of str into numbers and return as an array *size defaults to 4 usage: bs=require('binstr') wbdata=bs.unpack(get_prop_str(0x10d,0x1c)) -- return propset 3 white balance as 7 ints → 'In all cases, the numbers are assumed to be little endian file_browser(path) ''(since changeset #1359; since #1360 works better) This function allows you to run regular CHDK file browser from the script. When user will select a file, the command will return the string - a path to the selected file. The 'path' given as an argument is the startup directory for the file browser. Example code runs file browser in SCRIPTS directory and prints the path to the selected file: -- @title select a file -- startup_dir="A/CHDK/SCRIPTS" file=file_browser(startup_dir) print(file) When user will not select any file (in example exit file browser by pressing 'menu' button) command wil return nil value. Once browser is run by script it behaves exactly as CHDK file browser with all options - user can copy, cut and paste files, do RAW processings and other things that are allowed in browser run from menu. There's no way to control the things user can do. Load & Save CHDK configuration files (available since CHDK version 1.3) * set_config_autosave(<0|1>) * load_config_file(,) * save_config_file(,) Without file name the default filename is used. See this forum thread for more details. RAW development (available since CHDK version 0.8.4 / changeset #594) There are the following four new functions for merging RAW images directly in the camera: *'''set_raw_develop("filename") :Develop RAW on next shot. If filename is nil (or omitted), any pending raw develop is canceled. *'raw_merge_start(operation)' :Start merging process, operation is a number: 0'''=sum '''1=average. Other=error. *'raw_merge_add("filename")' :merge a file *'raw_merge_end()' :complete the merge operation. :*Error checking is minimal. If you pass an invalid filename, things may silently fail. If you call raw_merge_add or raw_merge_end without calling start first, or call raw_merge_start multiple times without an intervening end, the results are undefined. :*The RAW merge stuff runs in the same task as the script (the keyhook task), while raw operations from the menu run from the spytask. This appears to work, but it's a bit suspect. Sample script This script demonstrates the usage of the RAW development commands, it performs the requested RAW operation on n files. *You can specify what exposure number to start at, or use 0''' to specify the most recent. *The script works by counting down through the files until it find enough RAW files, so they don't need to be sequential. *It can optionally develop the resulting file. *The merged file will be named with the number of the last merged file, which will be the lowest number found. -- @title raw merge and develop @param a op: 0=sum 1=avg @default a 1 @param b start file: 0=latest @default b 0 @param c files to merge @default c 4 @param d develop ? 0=n 1=y @default d 0 based on work by fudgey and dsvilko http://chdk.setepontos.com/index.php/topic,2646.0.html -- rawpath="A/DCIM/100CANON/" rawprefix="CRW_" rawext=".CRW" -- no range check, so we can check error cond operation=a -- limit 1-9999 start=b -- sanity check ? numfiles=c develop=d~=0 --RAW_OPERATION_SUM=0 --RAW_OPERATION_AVERAGE=1 function fastshoot() press("shoot_half") repeat sleep(1) until get_shooting() true log("shooting...") press("shoot_full") release("shoot_full") release("shoot_half") repeat sleep(1) until get_shooting() ~= true end function leadingzeros(num) local zs="" if num < 10 then zs="000" elseif num < 100 then zs="00" elseif num < 1000 then zs="0" end return zs .. num end logfile=io.open("A/rawops.log","wb") io.output(logfile) function log(...) io.write(...) io.write("\n") end if start 0 then start = get_exp_count()%10000 end raw_merge_start(operation) log("raw_merge_start(",tostring(operation),")") count=0 i = start log("merging ",numfiles," files start at ",start) while count < numfiles and i > 0 do -- so we can get the name to develop rawbasename=rawpath..rawprefix..leadingzeros(i) rawname=rawbasename..rawext log("trying ",rawname) if os.stat(rawname) then log("raw_merge_add_file(",rawname,")") raw_merge_add_file(rawname) count = count + 1 end i = i - 1 end log("merged ",count," files") log("raw_merge_end()") raw_merge_end() if develop then log("developing...") -- only develop in rec mode if get_mode() then -- assumes input files were .cr* developname=rawbasename..".WAV" log("set_raw_develop(",developname,")") set_raw_develop(developname) fastshoot() else log("not in record mode") end end log("done!") logfile:close() ---- Flash parameters (available since CHDK version 0.8.7 / changeset #607) Note: please update List of Params as you see fit. Canon cameras store some parameters in onboard flash memory. These functions allow you to query them. *'''num=get_flash_params_count() : num is the number of parameters. Parameters are numbered starting form zero. *'str,num=get_parameter_data(id)' :str is the parameter value as a lua string, which may contain embedded NULLs or other non-printable characters. If the size of the flash parameter is 4 bytes or less, a second value is returned, containing the parameter value as a number. If the parameter id is invalid, or the parameter size is 0, then nil is returned for both values. Notes * parameter IDs and meanings vary between cameras. Using them will make your script non-portable, unless your script has code to check what camera it is running on (using get_buildinfo) and select the correct parameter IDs for each camera. * You can find useful parameter IDs in the CHDK source. * Setting parameter values is not supported yet. Sample script This script dumps the parameters from the internal flash memory and write them to a logfile paramdmp.log on the root folder of the memory card. Notes: *The parameter IDs may vary between cameras, so scripts using them will not be portable ! *This script is included in the 'complete' download packages from the Autobuild server -- dump parameters from internal flash memory NOTE: parameter ids may vary between cameras, so scripts using them will not be portable -- logfile=io.open("A/paramdmp.log","wb") for i=0,get_flash_params_count()-1 do s,n = get_parameter_data(i) logfile:write(i,": ") if s then -- string as hex for j=1,s:len() do logfile:write(string.format("0x%02x ",s:byte(j))) end -- string quoted logfile:write(string.format("%q",s)) -- as number, if available if n then logfile:write(string.format(" 0x%x %d",n,n)) end else logfile:write("nil") end logfile:write("\n") end logfile:close() ---- set_curve_state (available since CHDK version 0.9.6 / changeset #709) Set the status of curve function for postprocessing in scripts: set_curve_state(n) n: 0, 1, 2, 3, 4 = None, Custom, +1EV, +2EV, AutoDR ---- get_meminfo meminfo=get_meminfo(heapname) gets camera memory information If the heapname is valid, a table is returned with the following fields meminfo = { name -- string "system", "exmem". CHDK 1.3 also includes "aram" and "combined" chdk_malloc -- bool, this is the heap used by CHDK for malloc chdk_start -- number, load address of CHDK chdk_size -- number, size of CHDK image -- all the following are numbers, will not be set if not available start_address -- pool start, not set for "combined" end_address -- pool end, not set for "combined" total_size allocated_size allocated_peak allocated_count free_size free_block_max_size free_block_count } If heapname is not valid, false is returned. Which heapnames are valid depends on the port and CHDK version. NOTE * For very old vxworks cameras without GetMemInfo the only valid fields for the system heap will be those defined by chdk and free_block_max_size. In CHDK 1.2 and earlier * heapname may be "system" or "exmem" (on cameras with exmem configured) * if heapname not given, meminfo is returned for heap that CHDK is configured to allocate from at compile time. * The values of the allocated_* fields for exmem are not compatible with the same values for "system", and are generally not meaningful. CHDK 1.3 adds several changes to memory management which affect this function. * CHDK allocates memory from all available pools, so a new heap name "combined" is available, which gives the total amount of memory available to CHDK. This is now the default if no heapname is specified, and chdk_malloc is now set to true for all heaps. * For "combined" free_block_max_size gives the largest single free block. Other sizes and counters give the total from all available heaps. start_adress and end_address are not returned. * An additional heap called "aram" is available on some cameras. * The meaning of allocated_size, allocated_peak and allocated_count for exmem and aram now match the meaning in dryos. get_image_dir Get the current image directory as a string. Example: img=string.format('%s/IMG_%04d.JPG',get_image_dir(),get_exp_count()) notes * Outside of the shooting process, the above will normally get the path to the last image * When the directory updates is not well specified * Behavior of cameras with date based folder naming should be clarified (is it always the current date?) get_live_histo Available in CHDK 1.2 and later histogram,total=get_live_histo() returns a histogram of Y values from the viewport buffer (downsampled by HISTO_STEP_SIZE) histogramvalue = count, so it is zero based unlike a normal lua array total is the total number of pixels, may vary depending on viewport size ---- LogicalEvent API See Lua/Lua_Reference/Levent ---- Event procedure and native function API See Lua/Lua Reference/Native Function Calls ---- Changed Lua commands print_screen Logging can only be disabled by 'print_screen(false)'. Using 'print_screen(true)' enables logging in overwrite mode to LOG_0001.TXT. Using print_screen(n) enables logging in overwrite mode to LOG_nnnn.TXT if n>-10000. ? Using print_screen(n) enables logging in append mode to LOG_dddd.TXT if n< -10000 where d=abs(-10000-n). get_time get_time delivers a selectable part of the current date or time :→ Additional, optional parameters: Y'''ear, '''Month, D'''ay, '''hour, m'''inute or '''second :Usage: get_time("unit") , where unit can be Year, Month, Day, hour, minute or second ([ ]=optional/example) Note: you might want to use os.date (human readable) or os.time() (unix timestamp) instead. In both cases, having no parameters will return the current value. get_mode (available since CHDK version 0.6.7 / changeset #545) Returns the active mode of the camera (3 values): bool is_record, bool is_video, number mode. The mode number is a bit field with several different values, exactly as would be returned by mode_get() in the CHDK C code. See the CHDK source for more information. See also capmode. Usage: rec,vid,mode=get_mode() Sample script modestrings={ 'AUTO', 'P', 'TV', 'AV', 'M', 'PORTRAIT', 'NIGHT', 'LANDSCAPE', 'VIDEO_STD', 'VIDEO_SPEED', 'VIDEO_COMPACT', 'VIDEO_MY_COLORS', 'VIDEO_COLOR_ACCENT', 'VIDEO_COLOR_SWAP', 'STITCH', 'MY_COLORS', 'SCN_WATER', 'SCN_NIGHT', 'SCN_CHILD', 'SCN_PARTY', 'SCN_GRASS', 'SCN_SNOW', 'SCN_BEACH', 'SCN_FIREWORK', 'SCN_COLOR_ACCENT', 'SCN_COLOR_SWAP', 'VIDEO_HIRES', 'SCN_AQUARIUM', 'COLOR_ACCENT', 'SCN_NIGHT1', 'SCN_ISO_3200', 'SCN_SPORT', 'SCN_KIDS_PETS', 'INDOOR', 'KIDS_PETS', 'NIGHT_SNAPSHOT', 'DIGITAL_MACRO', 'SCN_FOLIAGE', 'VIDEO_TIME_LAPSE', 'SCN_INDOOR', 'SCN_PORTRAIT', 'SUPER_MACRO', 'VIDEO_PORTRAIT', 'VIDEO_NIGHT', 'VIDEO_INDOOR', 'VIDEO_FOLIAGE', 'VIDEO_SNOW', 'VIDEO_BEACH', 'VIDEO_AQUARIUM', 'VIDEO_SUPER_MACRO', 'VIDEO_STITCH', 'VIDEO_MANUAL', 'SPORTS', } rec,vid,mode=get_mode() print("rec:",rec,"vid:",vid) print("mode:",mode,tostring(modestringsbitand(mode,0xFF))) -- 0xFF is MODE_SHOOTING_MASK sleep(2000) ---- Drawings ---- Listed below are several Lua functions used to put simple graphical elements on the screen. You can draw pixels, straight lines, ellipses, rectangles and even text strings. Note : ''' For better-controlled drawing (and more importantly redrawing) there is a '''drawings.lua module described here: Lua Drawings Module. Commands available are: draw_pixel( x, y, cl ) *Puts pixel at (x,y) coordinates with a color cl; draw_line( x1, y1, x2, y2, cl) *Draws a line that begins at (x1,y1) and ends at (x2,y2) with a color cl; draw_rect( x1, y1, x2, y2, cl, th) *Draws a rectangle border which top-left corner is at (x1,y1), bottom-right at (x2,y2), with color cl and thickness of th pixels (thickness is an optional parameter, defaults to 1); draw_rect_filled( x1, y1, x2, y2, cl1, cl2, th) *Similar to above, but the border will be filled with color cl2; draw_ellipse( x, y, a, b, cl) *Draws ellipse shape which center is at (x,y), half-height is a'', half-width is ''b and color cl you can not specify thickness for an ellipse (yet?); draw_ellipse_filled( x, y, a, b, cl) *Similar to above, but the shape will be filled with color cl; draw_string( x, y, t, clt, clb) *Draws (writes?) a string t'', at (''x,y) where letters have color clt and background has color clb. *Starting with CHDK 1.3.0 , draw_string will also accept additional font scaling parameter as follows : **'draw_string( x,y,t,clt,clb,scale)' **'draw_string(x,y,t,clt,clb,xscake,yscale)' ***Scale values are 1 to 4 making the font six progressively larger, smaller font size not currently supported *You can not currently specify the font - the default CHDK font is used draw_clear() *Deletes all drawing objects. get_gui_screen_width() (CHDK 1.3.0 or later only) *Returns the screen width in pixels (usually either 360 or 480) get_gui_screen_height() (CHDK 1.3.0 or later only) *Returns the screen height in pixels (usually 240) About Colors In general you can use two types of colors - Canon palette, which is specific for each camera or more portable CHDK script palette. *Canon palette colors are numbers in a range 0-255. They are different for various cameras and even on one camera palette differs between modes (play, rec and even more). For example number 100 might for one camera mean blue in rec mode and yellow on play mode but for another camera red in rec mode and white in play mode. *CHDK script palette are numbers between 256-273 and they mean: #256 transparent (no color) #257 black #258 white #259 red #260 dark red #261 light red #262 green #263 dark green #264 light green #265 blue #266 dark blue #267 light blue #268 grey #269 dark grey #270 light grey #271 yellow #272 dark yellow #273 light yellow Note 1: Not all colors are exactly the same and exist on all cameras. You might expect, that every camera should have transparent, white, black, red, green ''and blue'' colors. In some cameras other tones might default to these basic colors. Nevertheless, CHDK script palette is much more portable. Note 2: Everything, that you draw on a screen will be wiped away, when screen is updated (for example on camera rotation, OSD changes and maybe in other cases. These simple Lua drawings are quite ephemeral. Mathematical functions (imath library) ---- Since changeset #2453 (CHDK 1.2) are some mathematical functions available. CHDK only knows integers. Decimal numbers are scaled with 3 decimals, 123.456 => 123456. (') represents a virtual decimal point. Please do not use in a real script! Constants *'imath.scale' = 1'000 : All values are around 1000 extended to 3 digits represent. *'imath.pi2' = 6'283 : 2*pi *'imath.pi' = 3'142 : pi *'imath.pi_2' = 1'571 : pi/2 Multiplication and Division *x = imath.muldiv(a, b, c) : -2147352'576 <= x, a, b, c <= 2147352'576 : c<>0 : x=(a x b / c) *x = imath.mul(a, b) : -2147352'576 <= x, a, b <= 2147352'576 : x=(a x b) *x = imath.div(a, c) : -2147352'576 <= x, a, c <= 2147352'576 : c<>0 : x=(a / c) Conversions( degrees <-> radians ) *res = imath.rad(x) : -16383'999 <= x <= 16383'999 : -285'938 <= res <= 285'938 *res = imath.deg(x) : -285'938 <= x <= 285'938 : -16383'999 <= res <= 16383'999 Trigonometry (radians) *x = imath.sinr(phi) : -16383'999 <= phi <= 16383'999 : -1'000 <= x <= 1'000 *x = imath.cosr(phi) : -16383'999 <= phi <= 16383'999 : -1'000 <= x <= 1'000 *x = imath.tanr(phi) : -16383'999 <= phi <= 16383'999 : -5698'696 <= x <= 2674'857 : phi=PI/2 or 3*PI/2 -> x<>inf. : tanr(PI/2)=-5698'696 : tanr(3*PI/2)=2674'857 *phi = imath.asinr(x) : -1'000 <= x <= 1'000 : -PI/2 <= phi <= PI/2 *phi = imath.acosr(x) : -1'000 <= x <= 1'000 : 0 <= phi <= PI *phi = imath.atanr(x) : -7035'005 <= x <= 7035'005 : -PI/2 <= phi <= PI/2 *r, theta = imath.polr(x, y) : -7035'005 <= x, y <= 7035'005 : 0 < r <= 9948'767 (0 = overflow) : -PI/2 <= theta <= PI/2 *x, y = imath.recr(r, theta) : -16383'999 <= r : theta, x, y <= 16383'999 : r<>0 Trigonometry (degrees) *x = imath.sind(phi) : -16383'999 <= phi <=16383'999 : -1'000 <= x <= 1'000 *x = imath.cosd(phi) : -16383'999 <= phi <=16383'999 : -1'000 <= x <= 1'000 *x = imath.tand(phi) : -16383'999 <= phi <=16383'999 : -16383'000 <= x <= 16383'000 : phi=90'000 or 270'000 -> x<>inf : tand(90'000|270'000)=-16383'000 *phi = imath.asind(x) : -1'000 <= x <= 1'000 : -90'000 <= phi <= 90'000 *phi = imath.acosd(x) : -1'000 <= x <= 1'000 : 0 <= phi <= 180'000 *phi = imath.atand(x) : -7035'005 <= x <= 7035'005 : phi = -90'000 <= phi <= 90'000 *r, theta = imath.pold(x, y) : -7035'005 <= x, y <= 7035'005 : 0 < r <= 9948'767 (0 = overflow) : -90'000 <= theta <= 90'000 *x, y = imath.recd(r, theta) : -16383'999 <= r, theta, x, y <= 16383'999 : r<>0 Logarithmic *res = imath.sqrt(x) : 0 <= x <= 16384'000 : 0 <= res <= 128'000 *res = imath.pow(x, y) : -16383'000 <= x^y <= 16383'000 *res = imath.log(x) : 0 < x <= 16383'999 : 0 <= res <= 9'704 *res = imath.log2(x) : 0 < x <= 16384'000 : 0 <= res <= 14'000 *res = imath.log10(x) : 0 < x <= 16383'999 : 0 <= res <= 4'214 Integer Conversion and Rounding *res='imath.int'(n) : int(5'010) = 5'000 : int(-5'010) = -5'000 *res='imath.frac'(n) : frac(5'010) = 0'010 = 10 : frac(-5'010) = -0'010 = -10 *res='imath.ceil'(n) : ceil(5'010) = 6'000 : ceil(-5'010) = -5'000 *res='imath.floor'(n) : floor(5'010) = 5'000 : floor(-5'010) = -6'000 *res='imath.round'(n) : round(5'010) = 5'000 : round(-5'010) = -5'000 Category:Lua Category:Scripting Category:Development